// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.designer.core;

import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.dengues.commons.IDenguesSharedImage;
import org.dengues.commons.connectivity.IConnectivitySettingsConstants;
import org.dengues.commons.utils.ImageUtil;
import org.dengues.core.IDesignerCoreService;
import org.dengues.core.codegen.ICodeGenerator;
import org.dengues.core.components.IComponentFilesNaming;
import org.dengues.core.components.IComponentsFactory;
import org.dengues.core.components.IXMLComponent;
import org.dengues.core.metadata.DatabaseContainer;
import org.dengues.core.metadata.MetadataDatabase;
import org.dengues.core.metadata.MetadataTable;
import org.dengues.core.metadata.MetadataUtils;
import org.dengues.core.process.ICompProcess;
import org.dengues.core.runprocess.IJavaETLProcessor;
import org.dengues.core.runprocess.JavaProcessorUtil;
import org.dengues.designer.core.codegen.ProcessCodeGenerator;
import org.dengues.designer.core.codegen.config.JETCodeGeneratorEmittersPoolFactory;
import org.dengues.designer.core.components.ComponentFilesNaming;
import org.dengues.designer.core.components.ComponentsFactory;
import org.dengues.designer.core.demos.ImportDemoProjectProvider;
import org.dengues.designer.core.i18n.Messages;
import org.dengues.designer.core.launch.JavaETLProcessor;
import org.dengues.designer.core.shadow.ShadowCompProcess;
import org.dengues.designer.core.sqldb.SqldbUtil;
import org.dengues.designer.core.sqldb.StartHsqldbServer;
import org.dengues.ui.prefs.connectivity.EConnectivityProperties;
import org.dengues.ui.prefs.connectivity.XMLFileManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jface.action.Action;
import org.eclipse.swt.widgets.Shell;
import org.osgi.framework.Bundle;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 2007-11-21 qiang.zhang $
 * 
 */
public class DesignerCoreService implements IDesignerCoreService {

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#getComponentFilesNaming()
     */
    public IComponentFilesNaming getComponentFilesNaming() {
        return new ComponentFilesNaming();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#getComponentsFactory()
     */
    public IComponentsFactory getComponentsFactory() {
        return new ComponentsFactory();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#initializeTemplates()
     */
    public void initializeTemplates() {
        JETCodeGeneratorEmittersPoolFactory.initialize();
        getJavaProcessor().synDenguesApi();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#getJavaProcessor(org.dengues.core.process.ICompProcess)
     */
    public IJavaETLProcessor getJavaProcessor(ICompProcess process, IPath path) {
        return new JavaETLProcessor(process, path);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#launchShadowProcess(org.dengues.core.components.IXMLComponent,
     * java.util.Properties)
     */
    public Process launchShadowProcess(IXMLComponent component, Properties properties) throws Exception {
        ShadowCompProcess shadowCompProcess = new ShadowCompProcess(component, properties);
        final JavaETLProcessor javaETLProcessor = new JavaETLProcessor(shadowCompProcess, new Path("shadow")); //$NON-NLS-1$
        try {
            return javaETLProcessor.run(XMLFileManager.parseString(properties
                    .getProperty(IConnectivitySettingsConstants.PROP_DEFN_JARLIST)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#getJavaProcessor()
     */
    public IJavaETLProcessor getJavaProcessor() {
        return new JavaETLProcessor();
    }

    private final StartHsqldbServer startHsqldbServer = new StartHsqldbServer();

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#createStartHsqldbServer()
     */
    public Action createStartHsqldbServer() {
        return startHsqldbServer;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#runSqlScript(org.eclipse.core.resources.IFile)
     */
    public ILaunch runSqlScript(IFile scriptFile, Map properties) {
        try {
            String driver = (String) properties.get(EConnectivityProperties.PROP_ID_DRIVER.getPropId());
            String rootpath = (String) properties.get(EConnectivityProperties.PROP_ID_ROOTPATH.getPropId());
            String database = (String) properties.get(EConnectivityProperties.PROP_ID_DATABASE.getPropId());
            String schema = (String) properties.get(EConnectivityProperties.PROP_ID_SCHEMA.getPropId());
            String url = (String) properties.get(EConnectivityProperties.PROP_ID_URL.getPropId());
            String user = (String) properties.get(EConnectivityProperties.PROP_ID_USER.getPropId());
            String password = (String) properties.get(EConnectivityProperties.PROP_ID_PASSWORD.getPropId());

            return SqldbUtil.runScriptTool(scriptFile, driver, rootpath, database, schema, url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // /*
    // * (non-Javadoc)
    // *
    // * @see org.dengues.core.IDesignerCoreService#getHsqlDatabase()
    // */
    // public DatabaseContainer getHsqlDatabase() throws SQLException {
    // DatabaseContainer container = new DatabaseContainer();
    // List<MetadataDatabase> bds = new ArrayList<MetadataDatabase>();
    //
    // MetadataDatabase database = new MetadataDatabase();
    // database.setDatabaseContainer(container);
    // database.setDatabaseName(DenguesProjectFactory.getDenguesProject().getName().toLowerCase());
    // bds.add(database);
    // container.setDatabases(bds);
    // try {
    // Connection hsqlConn = getCurrentConnection();
    // List<MetadataTable> metadataTables = MetadataUtils.getMetadataTables(database, hsqlConn);
    // database.setTables(metadataTables);
    // hsqlConn.close();
    // } catch (CoreException ex) {
    // ex.printStackTrace();
    // } catch (ClassNotFoundException ex) {
    // ex.printStackTrace();
    // }
    // return container;
    // }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#checkHsqldbConnection()
     */
    public boolean checkHsqldbConnection() {
        boolean isStart = SqldbUtil.checkConnection();
        StartHsqldbServer.setRunning(isStart);
        startHsqldbServer.setText(Messages.getString("DesignerCoreService.Start.Label")); //$NON-NLS-1$
        if (isStart) {
            startHsqldbServer.setImageDescriptor(ImageUtil.getDescriptor(IDenguesSharedImage.ACTION_STARTDB));
            startHsqldbServer.setText(Messages.getString("DesignerCoreService.Stop.Label")); //$NON-NLS-1$
        }
        return false;
    }

    // /*
    // * (non-Javadoc)
    // *
    // * @see org.dengues.core.IDesignerCoreService#getCurrentConnection()
    // */
    // public Connection getCurrentConnection() throws SQLException, CoreException, ClassNotFoundException {
    // return SqldbServerTracker.getDefault().getCurrentConn();
    // }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#getCodeGenerator()
     */
    public ICodeGenerator getCodeGenerator() {
        return new ProcessCodeGenerator();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#getDatabaseContainerFrommConnection(java.sql.Connection,
     * java.util.Properties)
     */
    public DatabaseContainer getDatabaseContainerFrommConnection(Connection connection, Map baseProperties) {
        DatabaseContainer container = new DatabaseContainer();
        List<MetadataDatabase> bds = new ArrayList<MetadataDatabase>();

        MetadataDatabase database = new MetadataDatabase();
        database.setDatabaseContainer(container);
        String property = (String) baseProperties.get(EConnectivityProperties.PROP_ID_DATABASE.getPropId());
        database.setDatabaseName(property);
        bds.add(database);
        container.setDatabases(bds);
        try {
            List<MetadataTable> metadataTables = MetadataUtils.getMetadataTables(database, connection);
            database.setTables(metadataTables);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return container;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#cleanTempFiles()
     */
    public void initJavaProject() {
        JavaETLProcessor javaETLProcessor = new JavaETLProcessor();
        try {
            IPackageFragment daoTempPkg = javaETLProcessor.getProjectPackage(JavaProcessorUtil.JAVA_SQLDBTEMP_PKG);
            if (daoTempPkg.exists()) {
                daoTempPkg.delete(true, null);
            }
            IPackageFragment codePkg = javaETLProcessor.getProjectPackage(JavaProcessorUtil.JAVA_PROJ_CODE_PKG);
            if (codePkg.exists()) {
                codePkg.delete(true, null);
            }
            IJavaProject javaProject = javaETLProcessor.getJavaProject();
            IProject project = javaProject.getProject();
            IFolder folder = project.getFolder(JavaProcessorUtil.SQL_SCRIPT_DIR);
            if (folder.exists()) {
                folder.delete(true, null);
            }
            project.refreshLocal(IResource.DEPTH_INFINITE, null);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.IDesignerCoreService#importDemoProject()
     */
    public void importDemoProject(Shell shell, IProgressMonitor monitor) {
        String prjName = IComponentsFactory.DENGUES_DEMOS_NAME;
        Bundle bundle = DesignerCorePlugin.getDefault().getBundle();
        URL componentURL = FileLocator.find(bundle, new Path(IComponentsFactory.DENGUES_DEMOS_NAME), null);
        URL url;
        try {
            url = FileLocator.toFileURL(componentURL);
            String sourcePath = url.getPath();
            ImportDemoProjectProvider.importProjectAs(shell, prjName, sourcePath, monitor);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
